package com.nodecollege.cloud.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.nodecollege.cloud.client.feign.LoginClient;
import com.nodecollege.cloud.common.constants.NCConstants;
import com.nodecollege.cloud.common.enums.ErrorEnum;
import com.nodecollege.cloud.common.model.LoginUser;
import com.nodecollege.cloud.common.model.NCResult;
import com.nodecollege.cloud.common.model.vo.ChatData;
import com.nodecollege.cloud.common.model.vo.LoginVO;
import com.nodecollege.cloud.common.utils.NCUtils;
import com.nodecollege.cloud.common.utils.RedisUtils;
import com.nodecollege.cloud.common.utils.ThreadUserUtils;
import com.nodecollege.cloud.core.ChatTypeEnum;
import com.nodecollege.cloud.core.SpringContextHolder;
import com.nodecollege.cloud.service.ChatService;
import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

/**
 * @author LC
 * @date 2020/2/26 23:07
 */
@Slf4j
@Primary
@Service
public class ChatServiceImpl extends ChatServiceAbstrat implements ChatService {

    @Autowired
    private LoginClient loginClient;

    @Autowired
    private RedisUtils redisUtils;

    @Value("${spring.application.name:default}")
    private String applicationName;

    /**
     * 消息处理
     *
     * @param chatData
     * @param channel
     */
    @Override
    public void handler(String chatData, Channel channel) {
        log.info("ChatHandlerServiceImpl handler 消息内容{}", chatData);
        ChatData data = JSONObject.parseObject(chatData, ChatData.class);
        NCResult checkLogin = checkLogin(data);
        if (!checkLogin.getSuccess()) {
            sendMsg(channel, checkLogin, 999);
            return;
        }
        ChatService chatService = (ChatService) SpringContextHolder.getBean(ChatTypeEnum.getClassByType(data.getRecordType()));
        chatService.handler(chatData, channel);
    }

    /**
     * 校验是否登陆
     *
     * @param chatData
     * @return
     */
    private NCResult checkLogin(ChatData chatData) {
        String accessToken = chatData.getAccessToken();
        String infoRandom = chatData.getInfoRandom();
        if (accessToken == null) {
            return NCResult.error(ErrorEnum.LOGIN_TIME_OUT);
        }
        String tokenKey = NCConstants.HEADER_ACCESS_TOKEN + applicationName + ":" + accessToken;
        LoginUser loginUser = redisUtils.get(tokenKey, LoginUser.class);
        if (NCUtils.isNullOrEmpty(loginUser) || !loginUser.getInfoRandom().equals(infoRandom)) {
            LoginVO loginVO = new LoginVO();
            loginVO.setToken(accessToken);
            NCResult<LoginUser> result = loginClient.getUserInfo(loginVO);
            if (result.getSuccess() && !result.getRows().isEmpty() && result.getRows().get(0) != null) {
                loginUser = result.getRows().get(0);
                redisUtils.set(tokenKey, loginUser, loginUser.getExpire());
            } else {
                return NCResult.error(ErrorEnum.LOGIN_TIME_OUT);
            }
        }
        ThreadUserUtils.setLoginUser(loginUser);
        return NCResult.ok();
    }
}
